package com.example.appjava;

import com.allqj.qjf.dictionary.util.DictUtil;
import com.allqj.qjf.service.CommonDict;
import com.example.appjava.dao.User;
import com.example.appjava.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @author sjw
 * @className HomeController
 * @date 2021/4/13 8:42
 * @description: TODO
 */
@RestController
@RequestMapping("/home")
public class HomeController {

    @Autowired
    private UserService userService;

    @GetMapping("/hello/{id}")
    public String hello(@PathVariable Integer id) throws Exception {
        System.out.println(id + "             " + Thread.currentThread().getId());
        //Thread.sleep(1000);
        if (id == 1)
            userService.test1();
        else if (id == 2)
            userService.test2();
        else if (id == 3)
            userService.test3();
        else if (id == 4)
            userService.test4();
        return "hello";
    }

    @GetMapping("/age/{age}")
    public List<User> users(@PathVariable Integer age) {
        return userService.uses(age);
    }


    @GetMapping("/push")
    public void push() {
        userService.pushSfx();
    }

    @GetMapping("/async")
    public Integer testAsync() {
        try {
            Future<Integer> a = userService.asyncFunc();
            return a.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return 2;
        } catch (ExecutionException e) {
            e.printStackTrace();
            return 3;
        }

    }


    @GetMapping("/aaa")
    public Object aaa() {
        return CommonDict.items(1);
    }

    @GetMapping("/dict/{dictType}")
    public Object dict(@PathVariable String dictType) {
        return DictUtil.items(dictType);
    }

    @GetMapping("/item/{dictType}/{itemCode}")
    public Object dict(@PathVariable String dictType, @PathVariable String itemCode) {
        return DictUtil.item(dictType, itemCode);
    }

    private void clearCache() {
        WeakRefItemInfo se = null;
        while ((se = (WeakRefItemInfo) queue.poll()) != null) {
            waekMap.remove(se.key);
            System.out.println("对象ID : " + se.key + "已经被JVM回收");
        }
    }

    private Map<Integer, WeakReference<ItemInfo>> map = new HashMap<>();
    private Map<Integer, WeakRefItemInfo> waekMap = new HashMap<>();
    private ReferenceQueue<ItemInfo> queue = new ReferenceQueue<>();

    @GetMapping("/cache1/{userId}")
    public ItemInfo cache1(@PathVariable Integer userId) {
        if (waekMap.containsKey(userId)) {
            WeakRefItemInfo weakRefItemInfo = waekMap.get(userId);
            if (weakRefItemInfo == null || weakRefItemInfo.get() == null) {
                System.out.println("缓存失效");
                clearCache();
                return null;
            } else {
                System.out.println("缓存get");
                System.out.println(weakRefItemInfo.key);
                return weakRefItemInfo.get();
            }
        } else {
            ItemInfo itemInfo = new ItemInfo();
            itemInfo.setId(userId);
            itemInfo.setTimestamp(System.currentTimeMillis());
            WeakRefItemInfo weakRefItemInfo = new WeakRefItemInfo(itemInfo, queue);
            System.out.println("缓存Put");
            waekMap.put(userId, weakRefItemInfo);
            return itemInfo;
        }
    }

    @GetMapping("/cache/{userId}")
    public ItemInfo cache(@PathVariable Integer userId) {
        if (map.containsKey(userId)) {
            WeakReference<ItemInfo> weakReference = map.get(userId);
            if (weakReference == null || weakReference.get() == null) {
                System.out.println("缓存失效");
                map.remove(userId);
                return null;
            } else {
                System.out.println("缓存Get");
                return weakReference.get();
            }
        } else {
            ItemInfo itemInfo = new ItemInfo();
            itemInfo.setId(userId);
            itemInfo.setTimestamp(System.currentTimeMillis());
            WeakReference<ItemInfo> weakReference = new WeakReference<>(itemInfo);
            System.out.println("缓存Put");
            map.put(userId, weakReference);
            return itemInfo;
        }
    }

    @GetMapping("/gc")
    public void gc() {
        System.gc();
    }


    @PostMapping("/dataSource")
    public RespVO mysql(@RequestBody ReqVO reqVO) throws Exception {
        System.out.println("-------------------------------------");
        if (reqVO == null || reqVO.getTenant() == null) return null;
        MySQLConfigVO vo = null;
        ElasticSearchConfigVO vo1 = null;
        MongoConfigVO vo2 = null;
        if ("1".equals(reqVO.getTenant())) {
            vo = new MySQLConfigVO();
            vo.setHost("192.168.10.96");
            vo.setPort(3306);
            vo.setUserName("root");
            vo.setPassword("123456");

            vo1 = new ElasticSearchConfigVO();
            vo1.setClusterName("elasticsearch");
            vo1.setClusterNodes("192.168.10.127:9300");

            vo2 = new MongoConfigVO();
            vo2.setConnStr("mongodb://dbadmin:qj123456789@192.168.10.127:27017,192.168.10.127:27018,192.168.10.127:27019/daily_report?repliaSet=rs0");

        } else if ("2".equals(reqVO.getTenant())) {
            vo = new MySQLConfigVO();
            vo.setHost("192.168.10.96");
            vo.setPort(3307);
            vo.setUserName("root");
            vo.setPassword("123456");

            vo1 = new ElasticSearchConfigVO();
            vo1.setClusterName("elasticsearch");
            vo1.setClusterNodes("192.168.10.127:9300");
        }
        RespVO respVO = new RespVO();
        respVO.setMySQLConfig(vo);
        respVO.setElasticSearchConfig(vo1);
        respVO.setMongoConfig(vo2);
        return respVO;
    }

    @GetMapping("/name/{id}")
    public String name(@PathVariable Integer id) {
        return userService.name(id);
    }
}
